Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add CallGraph struct, and dead-function-removal pass #1796

Open
wants to merge 20 commits into
base: main
Choose a base branch
from

Conversation

acl-cqc
Copy link
Contributor

@acl-cqc acl-cqc commented Dec 17, 2024

Closes #1753.

  • Tested by replacing use of remove_polyfuncs in feat!: Add monomorphization pass #1733; remove_polyfuncs is kept but deprecated and untested.
  • Note the CallGraph struct has no public accessors/etc. yet. I propose to leave this until we have more uses, as I found it hard to expose suitable for using petgraph utilities such as Bfs.

The longer-term plan is to integrate with #1672 by doing dataflow analysis and transforming to remove Calls that are locally/dynamically impossible, which will make more functions statically-unreachable and hence removable by this.

Copy link

codecov bot commented Dec 17, 2024

Codecov Report

Attention: Patch coverage is 88.39286% with 13 lines in your changes missing coverage. Please review.

Project coverage is 86.61%. Comparing base (1f841ae) to head (eaca2e7).
Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
hugr-passes/src/dead_func_removal.rs 85.71% 6 Missing and 3 partials ⚠️
hugr-passes/src/call_graph.rs 95.34% 1 Missing and 1 partial ⚠️
hugr-passes/src/monomorphize.rs 66.66% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1796      +/-   ##
==========================================
- Coverage   86.63%   86.61%   -0.03%     
==========================================
  Files         191      194       +3     
  Lines       34738    34883     +145     
  Branches    31571    31696     +125     
==========================================
+ Hits        30097    30214     +117     
- Misses       2940     2961      +21     
- Partials     1701     1708       +7     
Flag Coverage Δ
python 92.31% <ø> (-0.11%) ⬇️
rust 86.04% <88.39%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@acl-cqc acl-cqc changed the title feat: [Slightly WIP] Add CallGraph struct, and dead-function-removal pass feat!: [Slightly WIP] Add CallGraph struct, and dead-function-removal pass Dec 17, 2024
@ss2165
Copy link
Member

ss2165 commented Dec 17, 2024

can we deprecate remove_polyfuncs instead so we can include this in a non-breaking release?

@acl-cqc
Copy link
Contributor Author

acl-cqc commented Dec 17, 2024

can we deprecate remove_polyfuncs instead so we can include this in a non-breaking release?

Yes, well, we can, and I have, but I admit I am not singing the praises of the tooling here - deprecate has a "since" tag for tools that might use it, but IIUC I have to guess what the next version number will be (i.e. the version in which it'll be deprecated); and the re-export causes problems (I have to suppress a warning there - I tried putting the #[deprecated] only on the re-export but that did not generate a warning even when I used the function via the re-export). If I'm doing this wrong @ss2165 then please shout...

@acl-cqc acl-cqc changed the title feat!: [Slightly WIP] Add CallGraph struct, and dead-function-removal pass feat: [Slightly WIP] Add CallGraph struct, and dead-function-removal pass Dec 17, 2024
@acl-cqc acl-cqc changed the title feat: [Slightly WIP] Add CallGraph struct, and dead-function-removal pass feat: Add CallGraph struct, and dead-function-removal pass Dec 17, 2024
@acl-cqc acl-cqc force-pushed the acl/remove_dead_funcs branch from 31a7b44 to 08d9ebc Compare December 17, 2024 18:58
@acl-cqc acl-cqc force-pushed the acl/remove_dead_funcs branch from 08d9ebc to e29ffa2 Compare December 17, 2024 19:02
@acl-cqc acl-cqc marked this pull request as ready for review December 17, 2024 19:11
@acl-cqc acl-cqc requested a review from a team as a code owner December 17, 2024 19:11
@acl-cqc acl-cqc requested a review from tatiana-s December 17, 2024 19:11
Copy link
Contributor

@tatiana-s tatiana-s left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally looks good to me, just one comment mainly for my understanding.

fn traverse(
h: &impl HugrView,
node: Node,
enclosing: NodeIndex<u32>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for clarification - is enclosing the node in the call graph corresponding to the node node in the hugr or something else?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the (callgraph representation of) the nearest enclosing FuncDefn, so maybe the node's parent or an ancestor. I'll rename...

@tatiana-s tatiana-s requested a review from doug-q December 18, 2024 15:39
hugr-passes/src/call_graph.rs Outdated Show resolved Hide resolved
Comment on lines 149 to 152
/// * If the Hugr is non-Module-rooted and `entry_points` is non-empty
/// * If the Hugr is Module-rooted, but does not declare `main`, and `entry_points` is empty
/// * If the Hugr is Module-rooted, and `entry_points` is non-empty but contains nodes that
/// are not [FuncDefn](OpType::FuncDefn)s
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, I don't think the second should panic.

I think the interface would be cleaner if entry_points, maybe with a different name: must be FuncDefn or FuncDecl nodes that are immediate children of the root.

Now the first panic goes away, and the third would be an error with the offending nodes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to error, indeed. But FuncDefns inside a non-Module are invisible from outside (so unless you're gonna add new stuff inside the root - which you can do, but that's not linking, that's....arbitrary editing), so I've not allowed those as entry_points. I could be persuaded, it'd be easier from a code perspective not to check, but it feels wrong :-!

hugr-passes/src/call_graph.rs Outdated Show resolved Hide resolved
hugr-passes/src/call_graph.rs Outdated Show resolved Hide resolved
hugr-passes/src/call_graph.rs Outdated Show resolved Hide resolved
hugr-passes/src/call_graph.rs Outdated Show resolved Hide resolved
let reachable = reachable_funcs(&CallGraph::new(h), h, entry_points).collect::<HashSet<_>>();
let unreachable = h
.nodes()
.filter(|n| h.get_optype(*n).is_func_defn() && !reachable.contains(n))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should remove dead FuncDecls too

hugr-passes/src/call_graph.rs Outdated Show resolved Hide resolved
hugr-passes/src/call_graph.rs Outdated Show resolved Hide resolved
hugr-passes/src/call_graph.rs Outdated Show resolved Hide resolved
@doug-q
Copy link
Collaborator

doug-q commented Dec 19, 2024

Did you consider tracking in the Node weight whether it's a FuncDecl or a FuncDefn?

@doug-q doug-q closed this Dec 19, 2024
@doug-q doug-q reopened this Dec 19, 2024
@acl-cqc
Copy link
Contributor Author

acl-cqc commented Dec 20, 2024

Did you consider tracking in the Node weight whether it's a FuncDecl or a FuncDefn?

No, good idea, done

@acl-cqc acl-cqc requested a review from doug-q December 20, 2024 15:35
Copy link
Collaborator

@doug-q doug-q left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a pass to remove "unused" functions
4 participants